package com.ygqh.baby.controller.admin;

import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.stream.Collectors;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.collections4.CollectionUtils;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.ygqh.baby.ao.DataStatus;
import com.ygqh.baby.ao.Message;
import com.ygqh.baby.ao.OrderStatus;
import com.ygqh.baby.ao.PayType;
import com.ygqh.baby.ao.PromotionStatus;
import com.ygqh.baby.ao.PromotionType;
import com.ygqh.baby.ao.QueryInfo;
import com.ygqh.baby.ao.ResultSet;
import com.ygqh.baby.model.YgSkuInfo;
import com.ygqh.baby.po.Action;
import com.ygqh.baby.po.ActionOrder;
import com.ygqh.baby.po.ActionOrder.PickWay;
import com.ygqh.baby.po.ActionProduct;
import com.ygqh.baby.po.AdminUser;
import com.ygqh.baby.po.YgActionAddress;
import com.ygqh.baby.service.ActionOrderService;
import com.ygqh.baby.service.ActionProductService;
import com.ygqh.baby.service.ActionService;
import com.ygqh.baby.service.YgActionAddressService;
import com.ygqh.baby.service.YgSkuService;
import com.ygqh.baby.shiro.utils.SessionUtil;
import com.ygqh.baby.utils.DateConvertUtils;
import com.ygqh.baby.utils.YgStringUtils;

@Controller
@RequestMapping("/admin/action")
public class ActionController extends BaseController<Object, java.lang.Long> {

	@Autowired
	private ActionProductService actionProductService;
	@Autowired
	private ActionOrderService actionOrderService;
	@Autowired
	private YgActionAddressService ygActionAddressService;
	@Autowired
	private ActionService actionService;
	@Autowired
	private YgSkuService ygSkuService;

	@RequestMapping("getActionById")
	@ResponseBody
	public Message getActionById(Long actionId) {
		Action action = actionService.findById(actionId);
		return Message.success(action);
	}

	@RequestMapping("editAction")
	@ResponseBody
	public Message editAction(Action action) {

		AdminUser user = SessionUtil.getCurrentUser();
		Date date = new Date();
		if (action.getId() == null) {
			action.setCreateBy(user.getTrueName());
			action.setCreateTime(date);
		}
		action.setUpdateTime(date);
		action.setUpdateBy(user.getTrueName());

		int saveOrUpdate = actionService.saveOrUpdate(action);
		return Message.success(saveOrUpdate);
	}

	@RequestMapping("searchAction")
	@ResponseBody
	public Map<String, Object> searchAction(QueryInfo queryInfo, PromotionStatus pStatus, Date startDate, Date endDate, String q) {

		ResultSet<Action> search = actionService.search(queryInfo, pStatus, startDate, endDate, q);

		return search.toDatatables(null);
	}

	@RequestMapping("searchProduct")
	@ResponseBody
	public Map<String, Object> searchProduct(QueryInfo queryInfo, Long actionId, String q) {
		ResultSet<ActionProduct> search = actionProductService.search(queryInfo, actionId, q);

		return search.toDatatables(null);
	}

	@RequestMapping("findProductList")
	@ResponseBody
	public List<ActionProduct> findProductList(Long actionId) {

		List<ActionProduct> list = actionProductService.find(actionId);

		return list;
	}

	@RequestMapping("getSkuInfo")
	@ResponseBody
	public ActionProduct getSkuInfo(String skuCode, @RequestParam(required = true) Long actionId) {
		return actionProductService.findBySkuCode(skuCode, actionId);
	}

	@RequestMapping("getSkuInfoByBarCode")
	@ResponseBody
	public ActionProduct getSkuInfoByBarCode(String barCode, @RequestParam(required = true) Long actionId) {
		return actionProductService.findByBarCode(actionId, barCode);
	}

	@RequestMapping("updateStock")
	@ResponseBody
	public Message updateStock(Long pid, Long amount) {
		AdminUser user = SessionUtil.getCurrentUser();

		ActionProduct actionProduct = new ActionProduct();
		actionProduct.setId(pid);
		actionProduct.setAmount(amount);
		actionProduct.setRemark(user.getTrueName() + "更新库存 为 " + amount);
		int update = actionProductService.update(actionProduct);
		return Message.success(update);

	}

	@RequestMapping("saveOrder")
	@ResponseBody
	public Message saveOrder(@RequestParam String order, @RequestParam(defaultValue = "Cash") PayType payType,
			@RequestParam(defaultValue = "SinceLift") PickWay pickWay, String remark) {
		try {
			List<ActionOrder> actionOrder = JSON.parseObject(order, new TypeReference<List<ActionOrder>>() {
			});
			Long time = new Date().getTime();
			Date create = new Date();
			for (ActionOrder newOrder : actionOrder) {
				newOrder.setCreateTime(create);
				newOrder.setOrderId(time.toString());
				newOrder.setPaidTime(create);
				newOrder.setPickWay(pickWay);
				newOrder.setPayType(payType);
				newOrder.setRemark(remark);
				if (PickWay.SinceLift.equals(pickWay)) {
					newOrder.setOrderStatus(OrderStatus.TradeSuccess);
				} else {
					newOrder.setOrderStatus(OrderStatus.WaitingSend);
				}
				int row = actionOrderService.save(newOrder);
				if (row <= 0) {
					return Message.error("提交订单失败，商品[" + newOrder.getProductName() + "库存不足", newOrder.getSkuCode());
				}
			}
			return SUCCESS_MESSAGE;

		} catch (Exception ex) {
			ex.printStackTrace();
			return ERROR_MESSAGE;
		}

	}

	@RequestMapping("getSalesReport")
	@ResponseBody
	public Message getSalesReport(Long actionId, Date startDate) {
		Date endDate = startDate == null ? null : DateConvertUtils.addDay(startDate, 1);
		Map<String, Object> data = actionOrderService.selectSalesReport(actionId, startDate, endDate);
		return Message.success(data);
	}

	@RequestMapping("searchActionAddress")
	@ResponseBody
	public Map<String, Object> searchActionAddress(QueryInfo queryInfo, String userName, Date startDate, Date endDate, Boolean isSync, String q) {
		ResultSet<YgActionAddress> resultSet = ygActionAddressService.search(queryInfo, userName, startDate, endDate, isSync, q);
		return resultSet.toDatatables(null);

	}

	@RequestMapping("updateActionAddress")
	@ResponseBody
	public Message updateActionAddress(Long actionId, String receiver, String telphone, String address) {
		YgActionAddress ygActionAddress = new YgActionAddress(actionId, receiver, telphone, address);
		ygActionAddressService.update(ygActionAddress);
		return Message.success(null);

	}

	@RequestMapping("syncAction")
	@ResponseBody
	public Message syncAction(Long actionId) {
		return ygActionAddressService.syncAction(actionId);
	}

	@SuppressWarnings("resource")
	@RequestMapping("uploadActionProduct")
	@ResponseBody
	public Message readTemplate(@RequestParam("uploadFile") MultipartFile uploadFile, HttpServletRequest request, HttpServletResponse respons)
			throws IOException {

		InputStream is = uploadFile.getInputStream();
		XSSFWorkbook xssfWorkbook = new XSSFWorkbook(is);

		List<ActionProduct> productList = null;

		StringBuilder sb = new StringBuilder();
		try {
			// Read the Sheet
			for (int numSheet = 0; numSheet < xssfWorkbook.getNumberOfSheets(); numSheet++) {
				XSSFSheet xssfSheet = xssfWorkbook.getSheetAt(numSheet);
				if (xssfSheet == null) {
					continue;
				}
				// Read the Row
				for (int rowNum = 1; rowNum <= xssfSheet.getLastRowNum(); rowNum++) {
					XSSFRow xssfRow = xssfSheet.getRow(rowNum);
					if (xssfRow != null) {

						checkExcel(xssfRow, sb);
						if (sb.length() > 0) {
							return Message.error(sb.toString());
						}

						if (CollectionUtils.isEmpty(productList)) {
							productList = new ArrayList<>();
						}
						bulidProduct(xssfRow, productList, sb);
						if (sb.length() > 0) {
							return Message.error(sb.toString());
						}

					}
				}
			}
			Map<Long, List<ActionProduct>> collect = productList.stream().collect(Collectors.groupingBy(ActionProduct::getActionId));

			for (Entry<Long, List<ActionProduct>> entry : collect.entrySet()) {
				Long key = entry.getKey();
				List<ActionProduct> value = entry.getValue();
				List<String> skuList = value.stream().map(p -> p.getSkuCode()).collect(Collectors.toList());
				List<ActionProduct> existList = actionProductService.findBySkuCodeList(key, skuList);
				if (CollectionUtils.isNotEmpty(existList)) {
					sb.append(value.get(0).getActionName() + "中已下sku重复录入：");
					List<String> skuCodes = existList.stream().map(p -> p.getSkuCode()).collect(Collectors.toList());
					sb.append(skuCodes.toString());
				}
			}
			if (sb.length() > 0) {
				return Message.error(sb.toString());
			}

			buildSkuInfo(productList, sb);
			if (sb.length() > 0) {
				return Message.error(sb.toString());
			}

			actionProductService.addBatch(productList);
			return Message.success(null);
		} catch (Exception e) {
			e.printStackTrace();
			return Message.error(e.getMessage());
		}

	}

	private void buildSkuInfo(List<ActionProduct> productList, StringBuilder sb) {
		Map<String, List<ActionProduct>> collect = productList.stream().collect(Collectors.groupingBy(ActionProduct::getSkuCode));
		for (Entry<String, List<ActionProduct>> entry : collect.entrySet()) {
			YgSkuInfo skuInfo = ygSkuService.getSkuInfo(entry.getKey(), PromotionType.Ordinary);
			List<ActionProduct> value = entry.getValue();
			if (skuInfo == null) {
				sb.append(value.get(0).getActionName() + "中sku[" + entry.getKey() + "]不存在；");
				continue;
			}
			if (StringUtils.isEmpty(skuInfo.getBarCode())) {
				sb.append(value.get(0).getActionName() + "中sku[" + entry.getKey() + "]无条形码；");
			}
			if (StringUtils.isEmpty(skuInfo.getImgPath())) {
				sb.append(value.get(0).getActionName() + "中sku[" + entry.getKey() + "]无图片信息；");
			}
			value.stream().forEach(actionProduct -> {
				actionProduct.setBarCode(skuInfo.getBarCode());
				actionProduct.setImagePath(skuInfo.getImgPath());
			});
		}
	}

	private void bulidProduct(XSSFRow xssfRow, List<ActionProduct> productList, StringBuilder sb) {
		Long actionId = Long.parseLong(getValue(xssfRow.getCell(0)));
		String actionName = getValue(xssfRow.getCell(1));
		String productName = getValue(xssfRow.getCell(2));
		String productCode = getValue(xssfRow.getCell(3));
		String color = getValue(xssfRow.getCell(4));
		String skuCode = getValue(xssfRow.getCell(5));
		String size = getValue(xssfRow.getCell(6));
		BigDecimal price = new BigDecimal(getValue(xssfRow.getCell(7)));
		Long amount = Long.parseLong(getValue(xssfRow.getCell(8)));

		ActionProduct actionProduct = new ActionProduct(skuCode, actionId, actionName, productCode, productName, color, size, price, amount, DataStatus.Valid,
				"");
		if (productList.contains(actionProduct)) {
			sb.append("第" + xssfRow.getRowNum() + "行存在重复展会sku：" + skuCode);
			return;
		}
		productList.add(actionProduct);

	}

	private void checkExcel(XSSFRow xssfRow, StringBuilder sb) {
		String[] title = { "展会ID", "展会名称", "商品名称", "商品编码", "花色", "sku编码", "尺码", "单价", "数量" };
		for (int i = 0; i < 9; i++) {
			XSSFCell cell = xssfRow.getCell(0);
			String value = this.getValue(cell);

			if (StringUtils.isEmpty(value)) {
				sb.append("第" + xssfRow.getRowNum() + "行" + title[i] + "为空;");
			}
			if ((i == 0 || i == 3 || i == 5) && !YgStringUtils.isNum(value)) {
				sb.append("第" + xssfRow.getRowNum() + "行" + title[i] + "有误;");

			}
		}

	}

	/**
	 * 得到Excel表中的值
	 *
	 * @param hssfCell
	 *            Excel中的每一个格子
	 * @return Excel中每一个格子中的值
	 */
	@SuppressWarnings("static-access")
	private String getValue(XSSFCell hssfCell) {
		if (hssfCell == null)
			return null;
		if (hssfCell.getCellType() == hssfCell.CELL_TYPE_BOOLEAN) {
			// 返回布尔类型的值
			return String.valueOf(hssfCell.getBooleanCellValue());
		} else if (hssfCell.getCellType() == hssfCell.CELL_TYPE_NUMERIC) {
			DecimalFormat df = new DecimalFormat("0");
			String str = df.format(hssfCell.getNumericCellValue());
			// 返回数值类型的值
			return str;
		} else {
			// 返回字符串类型的值
			return String.valueOf(hssfCell.getStringCellValue());
		}
	}

	@RequestMapping(value = "addProductByBarCode")
	@ResponseBody
	public Message addProductByBarCode(@RequestParam String barCode, @RequestParam Long actionId, String skuInfos) {
		ActionProduct product = null;
		;
		if (!StringUtils.isEmpty(barCode)) {
			product = actionProductService.findByBarCode(actionId, barCode);
			if (product == null) {
				return Message.error("获取商品信息异常，请联系管理员", null);
			}
		}
		List<ActionProduct> productList = actionProductService.getProductList(product, skuInfos, actionId);
		BigDecimal totalPrice = actionProductService.getTotalPriceFromProductList(productList);
		Map<String, Object> data = new HashMap<String, Object>();
		data.put("totalPrice", totalPrice);
		data.put("product", product);
		return Message.success(data);
	}

	@RequestMapping(value = "saveActionPackToRedis")
	@ResponseBody
	public Message saveActionPackToRedis(@RequestParam Long[] packId, Date endDate) {
		endDate = endDate != null ? endDate : DateConvertUtils.parse("2018-07-15", "yyyy-MM-dd");
		actionProductService.saveActionPackToRedis(packId, endDate);
		return SUCCESS_MESSAGE;
	}

	@RequestMapping(value = "closeWaitingPayOrder")
	@ResponseBody
	public Message closeWaitingPayOrder(@RequestParam Long actionId, Date startDate, Date endDate) {
		actionOrderService.updateOrderToClose(actionId, startDate, endDate);
		return Message.success(null);
	}
}
